A typical data storage system includes an input/output (I/O) cache and a set of disk drives. The I/O cache is volatile storage (i.e., semiconductor memory) that temporarily buffers data transferred between an external device (e.g., a host) and the set of disk drives.
One conventional data storage system further includes a front-end interface and a back-end interface. The front-end interface operates as an interface between the external device and the I/O cache by moving blocks of data (e.g., 512 byte sections) between the external device and the I/O cache. The back-end interface operates as an interface between the I/O cache and the set of disk drives by moving the data blocks between the I/O cache and the set of disk drives.
Conventional data storage systems such as the one described above typically use a track table to determine whether data blocks, which reside in the set of disk drives, also reside in the I/O cache. For example, suppose that the external device requests a particular data block. If the requested data block resides in the I/O cache (e.g., due to the external device recently writing the data block to the I/O cache, due to previously reading the data block from the I/O cache, due to prefetching the data block from the set of disk drives, etc.), the data storage system can quickly fulfill the request by simply providing the requested data block from the I/O cache, rather than retrieving the requested data block all the way from the set of disk drives.
The above-described conventional data storage system uses a track table to keep track of which data blocks reside in the I/O cache. The track table includes an entry for every data block location available in the set of disk drives. If a particular data block in the set of disk drives does not reside in the I/O cache, the entry in the track table for that data block includes an empty pointer (e.g., NULL). In response to a request for the data block, the front-end interface finds the empty pointer in the track table entry for that data block and notifies the back-end interface to transfer the data block to the I/O cache. After the back-end interface transfers the data block to the I/O cache, the front-end interface conveys the data block from the I/O cache to the external device.
However, if the particular data block in the set of disk drives also resides in the I/O cache, the entry in the track table for that data block includes a pointer to the location (i.e., a cache slot) of the data block in the I/O cache (e.g., a cache slot which is addressable by the disk, cylinder and head location of the particular data block on disk). In this situation, when the front-end interface looks in the track table, the front-end interface finds an I/O cache pointer in the entry for the data block rather than an empty pointer. Accordingly, the front-end interface can provide the data block from the I/O cache to the external device without having to retrieve the data block from the set of disk drives and thus avoid burdening the back-end interface.